package com.lyf.service.admin.impl;

import com.lyf.mapper.admin.ReportMapper;
import com.lyf.mapper.admin.WorkSpaceMapper;
import com.lyf.service.admin.ReportService;
import com.lyf.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkSpaceMapper workSpaceMapper;
    @Autowired
    private ReportService reportService;

    /**
     * 营业额统计
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getdateList(begin,end);
        // 查询每天的营业额数据
        List<TurnoverReportVO> turnoverData = reportMapper.turnoverStatistics(begin, end);
        
        // 构建日期字符串（逗号分隔）
        String dateStr =  StringUtils.join(dateList,",");

        // 构建营业额字符串（逗号分隔）
        String turnoverStr = dateList.stream()
                .map(date -> {
                    // 在查询结果中查找对应日期的营业额
                    return turnoverData.stream()
                            .filter(data -> data.getDateList().equals(date.toString()))
                            .map(data -> data.getTurnoverList())
                            .findFirst()
                            .orElse("0.0");
                })
                .collect(Collectors.joining(","));
        
        // 构造并返回结果
        return TurnoverReportVO.builder()
                .dateList(dateStr)
                .turnoverList(turnoverStr)
                .build();
    }

    /**
     * 用户统计
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getdateList(begin,end);
        List<UserReportVO> userData = reportMapper.userStatistics(begin, end);
        // 构建日期字符串（逗号分隔）
        String dateStr =  StringUtils.join(dateList,",");
        // 构建总用户数字符串（逗号分隔）
        // 用户总数初始为0，遍历数据，如果某天有新用户创建就加到总数变量中，然后拼接到字符串上。
        String totalUserStr = dateList.stream()
                .map(date -> {
                    int totalUser = 0;
                    for (UserReportVO data : userData) {
                        LocalDate tempDate = LocalDate.parse(data.getDateList());
                        if (tempDate.isBefore(date) || tempDate.isEqual(date)) {
                            totalUser += Integer.parseInt(data.getNewUserList());
                        }else{
                            break;
                        }
                    }
                    return String.valueOf(totalUser);
                })
                .collect(Collectors.joining(","));
        // 构建新增用户数字符串（逗号分隔）
        String newUserStr = dateList.stream()
                .map(date -> {
                    return userData.stream()
                            .filter(data -> data.getDateList().equals(date.toString()))
                            .map(data -> data.getNewUserList())
                            .findFirst()
                            .orElse("0");
                })
                .collect(Collectors.joining(","));
        return UserReportVO.builder()
                .dateList(dateStr)
                .totalUserList(totalUserStr)
                .newUserList(newUserStr)
                .build();
    }

    /**
     * 订单统计
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getdateList(begin,end);
        List<OrderReportVO> orderData = reportMapper.orderStatistics(begin, end);
        // 构建日期字符串（逗号分隔）
        String dateStr = StringUtils.join(dateList,",");

        // 构建订单总数字符串（逗号分隔）
        String orderCountStr = dateList.stream()
                .map(date -> {
                    return orderData.stream()
                            .filter(data -> data.getDateList().equals(date.toString()))
                            .map(data -> data.getOrderCountList())
                            .findFirst()
                            .orElse("0");
                })
                .collect(Collectors.joining(","));

        // 构建有效订单数字符串（逗号分隔）
        String validOrderCountStr = dateList.stream()
                .map(date -> {
                    return orderData.stream()
                            .filter(data -> data.getDateList().equals(date.toString()))
                            .map(data -> data.getValidOrderCountList())
                            .findFirst()
                            .orElse("0");
                })
                .collect(Collectors.joining(","));
        // 计算总订单数和有效订单数
        Integer totalOrderCount = orderData.stream()
                .mapToInt(data -> Integer.parseInt(data.getOrderCountList()))
                .sum();
        Integer validOrderCount = orderData.stream()
                .mapToInt(data -> Integer.parseInt(data.getValidOrderCountList()))
                .sum();

        // 计算订单完成率（保留2位小数）
        Double orderCompletionRate = 0.0;
        if (totalOrderCount != 0) {
            BigDecimal rate = new BigDecimal(validOrderCount)
                    .divide(new BigDecimal(totalOrderCount), 4, RoundingMode.HALF_UP);
            orderCompletionRate = rate.setScale(2, RoundingMode.HALF_UP).doubleValue();
        }
        return OrderReportVO.builder()
                .dateList(dateStr)
                .orderCountList(orderCountStr)
                .validOrderCountList(validOrderCountStr)
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }

    /**
     * 获取指定日期范围内的日期列表
     *
     * @param begin
     * @param end
     * @return
     */
    public List<LocalDate> getdateList(LocalDate begin,LocalDate end) {
        // 创建日期范围列表
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate currentDate = begin;
        while (!currentDate.isAfter(end)) {
            dateList.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }
        return dateList;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List<LocalDate> dataList = getdateList(begin,end);
        List<SalesTop10ReportVO> salesTop10ReportVO = reportMapper.top10(begin, end);
        
        // 安全地构建商品名称字符串（逗号分隔）
        String nameList = salesTop10ReportVO.stream()
                .filter(Objects::nonNull) // 过滤掉null元素
                .map(SalesTop10ReportVO::getNameList)
                .filter(Objects::nonNull) // 过滤掉null值
                .collect(Collectors.joining(","));

        // 安全地构建商品销量数字符串（逗号分隔）
        String numberList = salesTop10ReportVO.stream()
                .filter(Objects::nonNull) // 过滤掉null元素
                .map(SalesTop10ReportVO::getNumberList)
                .filter(Objects::nonNull) // 过滤掉null值
                .collect(Collectors.joining(","));
                
        return SalesTop10ReportVO.builder()
                .nameList(nameList)
                .numberList(numberList)
                .build();
    }

    @Override
    public void exportBusinessesData(HttpServletResponse response) throws IOException {
        // 查询数据库获取近30天的相关运营数据
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);

        List<LocalDate> dateList = getdateList(begin,end);

        // 概览数据
        BusinessDataVO businessData= workSpaceMapper.getBusinessData(null,begin,end);

        // 明细数据
        List<BusinessDataVO> detailList = new ArrayList<>();
        for (LocalDate date : dateList){
            BusinessDataVO businessDataVO = workSpaceMapper.getBusinessData(date,null,null);
            // 检查营业数据，如果有字段值为null则设置为0
            businessDataVO.setTurnover(businessDataVO.getTurnover() == null ? 0.0 : businessDataVO.getTurnover());
            businessDataVO.setUnitPrice(businessDataVO.getUnitPrice() == null ? 0.0 : businessDataVO.getUnitPrice());
            businessDataVO.setNewUsers(businessDataVO.getNewUsers() == null ? 0 : businessDataVO.getNewUsers());
            businessDataVO.setValidOrderCount(businessDataVO.getValidOrderCount() == null ? 0 : businessDataVO.getValidOrderCount());
            businessDataVO.setOrderCompletionRate(businessDataVO.getOrderCompletionRate() == null ? 0.0 : businessDataVO.getOrderCompletionRate());
            detailList.add(businessDataVO);
        }

        // 通过POI将数据写入excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/BusinessExcelTemplate.xlsx");
        // 基于模板创建excel
        XSSFWorkbook workbook = new XSSFWorkbook(in);
        // 获取工作表
        XSSFSheet sheet = workbook.getSheet("Sheet1");

        // 填充数据
        sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);

        // 填充概览数据
        XSSFRow row = sheet.getRow(3);
        row.getCell(2).setCellValue(businessData.getTurnover());
        row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
        row.getCell(6).setCellValue(businessData.getNewUsers());

        row = sheet.getRow(4);
        row.getCell(2).setCellValue(businessData.getValidOrderCount());
        row.getCell(4).setCellValue(businessData.getUnitPrice());

        // 填充明细数据
        for (int i = 0; i < 30; i++){
            row = sheet.getRow(i + 7);
            row.getCell(1).setCellValue(dateList.get(i).toString());
            row.getCell(2).setCellValue(detailList.get(i).getTurnover());
            row.getCell(3).setCellValue(detailList.get(i).getValidOrderCount());
            row.getCell(4).setCellValue(detailList.get(i).getOrderCompletionRate());
            row.getCell(5).setCellValue(detailList.get(i).getUnitPrice());
            row.getCell(6).setCellValue(detailList.get(i).getNewUsers());
        }
        // 通过输出流将excel文件下载到客户端
        ServletOutputStream out = response.getOutputStream();
        workbook.write(out);
        workbook.close();

        // 释放资源
        out.close();
        in.close();
        workbook.close();
    }
}